const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const copyWebpackPlugin = require('copy-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const os = require('os');
const HappyPack = require('happypack');
const happyThreadPool = HappyPack.ThreadPool({
  size: os.cpus().length
});

module.exports = function (opts, argv) {
  const options = opts || {};

  const config = {
    entry: {
      main: path.resolve(__dirname, './src/main.js')
    },
    output: {
      path: path.resolve(__dirname, './dist/'),
      filename: '[name]-[hash].js',
      chunkFilename: 'modules/[name]-[hash].js',
      publicPath: '/'
    },

    optimization: {
      usedExports: true,
      minimizer: [
        // 多线程压缩
        new ParallelUglifyPlugin({
          cacheDir: '.cache/',
          uglifyJS: {
            output: {
              comments: false,
              beautify: false
            },
            warnings: false,
            compress: {
              drop_console: true,
              collapse_vars: true,
              reduce_vars: true
            }
          }
        }),
      ],
      splitChunks: {
        // 对entry进行拆分
        chunks: 'all',
        minSize: 30000,
        cacheGroups: {
          vueFullFamily: {
            test: /[\\/]node_modules[\\/]vue[\\/]|vue-router|vuex|axios/,
            priority: 20,
            name: 'vueFullFamily',
            enforce: true
          },
          vendor: {
            test: /node_modules/,
            priority: 10,
            name: 'vendor',
            enforce: true
          },
          default: {
            minChunks: 2,
            priority: 5,
            reuseExistingChunk: true
          }
        }
      }
    },

    module: {
      rules: [
        {
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          enforce: 'pre',
          include: [path.resolve(__dirname, './src')],
          options: {
            formatter: require('eslint-friendly-formatter'),
            emitWarning: false
          }
        },
        {
          test: /\.vue$/,
          use: [{
            loader: 'vue-loader'
          }],
          exclude: /node_modules/
        },
        {
          test: /\.js$/,
          use: [
            'happypack/loader?id=happybabel'
          ],
          exclude: /node_modules/
        },
        {
          test: /\.less$/,
          use: [
            'style-loader',
            'css-loader',
            'postcss-loader',
            'less-loader'
          ]
        },
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader',
            'postcss-loader'
          ]
        },
        {
          test: /\.(png|jpg|jpeg|gif)\??.*$/,
          use: [{
            loader: 'url-loader',
            options: {
              limit: 5120,
              name: 'img/[name].[ext]?[hash]'
            }
          }]
        },
        {
          test: /\.(eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,
          use: [{
            loader: 'file-loader',
            options: {
              name: 'fonts/[name].[ext]?[hash]'
            }
          }]
        }
      ]
    },

    plugins: [
      // html 入口文件生成插件
      new HtmlWebpackPlugin({
        template: 'src/index.ejs'
      }),
      new OptimizeCssAssetsPlugin({
        assetNameRegExp: /\.css$/g,
        cssProcessor: require('cssnano'),
        cssProcessorOptions: {
          discardComments: {
            removeAll: true
          }
        },
        canPrint: true
      }),
      // 文件复制插件
      new copyWebpackPlugin([{
        from: path.resolve(__dirname, 'src/assets'),
        to: path.resolve(__dirname, 'dist/assets')
      }]),
      // 环境变量注入插件
      new webpack.DefinePlugin({
        'process.env': {
          'NODE_ENV': JSON.stringify(options.NODE_ENV)
        }
      }),
      // 多进程打包
      new HappyPack({
        id: 'happybabel',
        loaders: ['babel-loader?cacheDirectory=true'],
        threadPool: happyThreadPool,
        verbose: true
      }),

      new VueLoaderPlugin(),
      new MonacoWebpackPlugin()
    ],
    resolve: {
      extensions: ['.js', '.css', '.vue'],
      // 直接指定模块库的位置
      modules: [
        path.resolve(__dirname, 'src'),
        path.resolve(__dirname, 'node_modules')
      ],
      alias: {
        '@': path.resolve(__dirname, 'src')
      }
    },

    devtool: false
  };

  return config;
};
